package leetcode_bin_tree_test;

import bin_tree.TreeNode;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * 面试题 04.04. 检查平衡性
 */
public class IsBalanced {
    public boolean isBalanced(TreeNode root) {
        // 自上而下的递归
        // 对每个节点求其两子树高度，并求差绝对值判断是否大于一
        // 使用前序遍历
//        if (root == null) {
//            return true;
//        }
//        int leftH = height(root.left);
//        int rightH = height(root.right);
//        // 如果当前节点符合条件继续判断子节点
//        if (Math.abs(leftH - rightH) > 1) {
//            return false;
//        }
//        return isBalanced(root.left) && isBalanced(root.right);
        // 以上方法每个节点都会重复调用height

        // 优化 使用自下而上的递归，这样每个节点就只用调用一次height，它的父结点只需要加一即可
        // 后序遍历
        // 在求高度的同时，看其左右是否平衡
        if (root == null) {
            return true;
        }
        return height(root) > 0;
    }

    /**
     * 后序遍历求树高度，若树中含有不平衡子树返回-1
     * @param root
     * @return
     */
    private int height(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int left = height(root.left);
        int right = height(root.right);
        if (left == -1 || right == -1 || Math.abs(left - right) > 1) {
            // 只要子树中含有一棵不平衡树，树的高度就返回-1
            return -1;
        }
        return 1 + Math.max(left, right);
    }

    /**
     * 求子树高度
     * @param node
     * @return
     */
//    private int height(TreeNode node) {
//        if (node == null) {
//            return 0;
//        }
//        return 1 + Math.max(height(node.left), height(node.right));
//    }
}
